package service

import (
	"bytes"
	"fmt"

	"github.com/vmihailenco/msgpack"
)

type MessageType byte

const (
	Login    MessageType = 1
	Ping     MessageType = 2
	Pong     MessageType = 3
	ChatText MessageType = 4
)

type Message struct {
	Type   MessageType
	Length uint64
	buffer bytes.Buffer
	errs   error
}

func NewMessage() *Message {
	return &Message{
		buffer: *bytes.NewBufferString(""),
	}
}

func (m *Message) Bytes() ([]byte, error) {
	if m.errs != nil {
		return nil, m.errs
	}
	t := uint64(m.buffer.Len())
	var buff bytes.Buffer
	buff.WriteByte(byte(m.Type))
	buff.Write(encodeLength(t))
	buff.Write(m.buffer.Bytes())
	return buff.Bytes(), nil
}

func intToBytes(i uint64) []byte {
	var buff []byte
	if i <= 0x7f {
		buff = append(buff, byte(i))
		return buff
	}
	if i <= 0xff7f {
		buff = append(buff, 0xff, byte(i))
		return buff
	}
	if i <= 0xffff7f {
		buff = append(buff, 0xff, 0xff, byte(i))
		return buff
	}
	if i <= 0xffffff7f {
		buff = append(buff, 0xff, 0xff, 0xff, byte(i))
		return buff
	}
	return nil
}

func (m *Message) SetType(t MessageType) *Message {
	m.Type = t
	return m
}

func (m *Message) SetPayload(i interface{}) *Message {
	err := msgpack.NewEncoder(&m.buffer).Encode(i)
	if err != nil {
		m.errs = fmt.Errorf("encode payload error: %v", err)
	}
	return m
}

func (m *Message) Valid() error {
	return nil
}
